﻿using Kinlo.Entitys;
using Kinlo.MESDocking;
using NPOI.OpenXmlFormats;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using UIWindows.Commands;
using UIWindows.Domains;
using UIWindows.GlobalStatics;
using UIWindows.Models;
using UIWindows.Tools;
using UIWindows.Tools.Helper;
using UIWindows.UserControls;
using UIWindows.Views;
using XingLucifer.Devices;
using XingLucifer.IBase.Enums;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace UIWindows.ViewModels
{
    public class ManualWeightViewModel : ViewModelBase
    {
        #region 双向绑定
        private string _barcode;
        /// <summary>
        /// 电池条码
        /// </summary>
        //public string Barcode
        //{
        //    get { return _barcode; }
        //    set { SetProperty(ref _barcode, value); }
        //}
        
        public string Barcode
        {
            get { return _barcode; }
            set 
            { 
                if(IsAuto&& value!="")
                {
                    BarcodeInput(value);
                }
                if (IsAuto && value.Length > "03HCE0950000AYD6S3100394".Length)
                {
                    value = value.Substring(value.Length - 1, 1); ;
                }
                SetProperty(ref _barcode, value); 
            }
        }
        private string _strartTime;
        /// <summary>
        /// 开始时间
        /// </summary>
        public string StrartTime
        {
            get { return _strartTime; }
            set { SetProperty(ref _strartTime, value); }
        }
        private double _BeforeWeighing;
        /// <summary>
        /// 干重重
        /// </summary>
        public double BeforeWeighing
        {
            get { return _BeforeWeighing; }
            set { SetProperty(ref _BeforeWeighing, value); }
        }
        private double _afterWeighing;
        /// <summary>
        /// 后称重
        /// </summary>
        public double AfterWeighing
        {
            get { return _afterWeighing; }
            set { SetProperty(ref _afterWeighing, value); }
        }
        private double _CurrentWeight;
        /// <summary>
        /// 当前重量
        /// </summary>
        public double CurrentWeight
        {
            get { return _CurrentWeight; }
            set { SetProperty(ref _CurrentWeight, value); }
        }
        //  private double _InjectionVolume;
        /// <summary>
        /// 注液量
        /// </summary>
        //public double InjectionVolume
        //{
        //    get { return _InjectionVolume; }
        //    set { SetProperty(ref _InjectionVolume, value); }
        //}
        //private double _refillInjectionVolume;
        /// <summary>
        /// 补液量
        /// </summary>
        //public double RefillInjectionVolume
        //{
        //    get { return _refillInjectionVolume; }
        //    set { SetProperty(ref _refillInjectionVolume, value); }
        //}
        private double _actualTotalInjectionVolume;
        /// <summary>
        /// 保液量
        /// </summary>
        public double ActualTotalInjectionVolume
        {
            get { return _actualTotalInjectionVolume; }
            set { SetProperty(ref _actualTotalInjectionVolume, value); }
        }
        private string _rangeFluidRate = string.Empty;
        /// <summary>
        /// 保液量范围
        /// </summary>
        public string RangeFluidRate
        {
            get { return _rangeFluidRate; }
            set { SetProperty(ref _rangeFluidRate, value); }
        }
        private double _totalInjectionVolumeDeviationValue;
        /// <summary>
        /// 保液量偏差
        /// </summary>
        public double TotalInjectionVolumeDeviationValue
        {
            get { return _totalInjectionVolumeDeviationValue; }
            set { SetProperty(ref _totalInjectionVolumeDeviationValue, value); }
        }

        private ResultTypes _leakResult;
        /// <summary>
        /// 测漏结果
        /// </summary>
        public ResultTypes LeakResult
        {
            get { return _leakResult; }
            set { SetProperty(ref _leakResult, value); }
        }
        private ResultTypes _Results;
        /// <summary>
        /// 结果
        /// </summary>
        public ResultTypes Results
        {
            get { return _Results; }
            set { SetProperty(ref _Results, value); }
        }
        private ResultTypes _TotalResult;
        /// <summary>
        /// 总结果
        /// </summary>
        public ResultTypes TotalResult
        {
            get { return _TotalResult; }
            set { SetProperty(ref _TotalResult, value); }
        }

        private string _msg = string.Empty;
        /// <summary>
        /// 提示消息
        /// </summary>
        public string Msg
        {
            get { return _msg; }
            set { SetProperty(ref _msg, value); }
        }
        private bool isAuto = false;
        /// <summary>
        /// 手动模式
        /// </summary>
        public bool IsAuto
        {
            get { return isAuto; }
            set {
                TxTIsAuto = !value;
                SetProperty(ref isAuto, value); 
            }
        }
        private bool txtIsAuto = false;
        /// <summary>
        /// 手动模式
        /// </summary>
        public bool TxTIsAuto
        {
            get { return txtIsAuto; }
            set { SetProperty(ref txtIsAuto, value); }
        }
        #endregion

        private TemporaryStatic _temporaryStatic;
        private ParameterStatic _parameterStatic;
        private SystemConfigStatic _systemConfigStatic;
        private DeviceConfigStatic _deviceConfigStatic;
        public ManualWeightViewModel(TemporaryStatic temporaryStatic, ParameterStatic parameterStatic, SystemConfigStatic systemConfigStatic, DeviceConfigStatic deviceConfigStatic)
        {
            Msg = string.Empty;
            KeyboardHook.RegistrationListening(24, GetBarCode);
            _temporaryStatic = temporaryStatic;
            _parameterStatic = parameterStatic;
            _systemConfigStatic = systemConfigStatic;
            _deviceConfigStatic = deviceConfigStatic;
            IsAuto = false;
            TxTIsAuto = true;
        }
        /// <summary>
        /// 扫码回调
        /// </summary>
        /// <param name="barcode"></param>
        public void GetBarCode(string barcode)
        {
            LogAdd($"[手持扫码枪] 返回：{barcode}");
            barcode = System.Text.RegularExpressions.Regex.Match(barcode, _systemConfigStatic.SCM.BarcodeRules, System.Text.RegularExpressions.RegexOptions.Compiled).Value;
            LogAdd($"[手持扫码枪] 校验后：{barcode}");
            if (!string.IsNullOrEmpty(barcode))
            {
                
                WeighingBusiness(barcode).ConfigureAwait(false);
            }
            else
            {
                LogAdd("[手工补液称] 条码不符合规则!");
            }
        }
        //public DelegateCommand<string> BarcodeInputCommand => new DelegateCommand<string>((text) =>
        //{
        //    // 在这里可以直接访问传递过来的最新的 Barcode 值

        //    // 设置一个阈值，比如 24
        //    int maxLength = "03HCE0950000AYD6S3100394".Length;
        //    // 在这里进行处理
        //    if (text.Length > maxLength)
        //    {
        //        // 超过阈值，进行相应的处理
        //        Barcode ="";
        //    }else if(text.Length== maxLength)
        //    {

        //        //GetBarCode(text);
        //        Barcode = "";
        //     }
        //});
        public void BarcodeInput(string text)
        {

            // 设置一个阈值，比如 24
            int maxLength = "03HCE0950000AYD6S3100394".Length;
            // 在这里进行处理
            if (text.Length > maxLength)
            {
                // 超过阈值，进行相应的处理
                //var aa= text.Substring(text.Length - 1, 1);
                //Barcode = text.Substring(text.Length - 1, 1);
            }
            else if (text.Length == maxLength)
            {

                GetBarCode(text);
                //Barcode = "";
            }
        }

        private async Task WeighingBusiness(string barcode)
        {
            
        }
        public double? GetWeiging(Models.Devices.DeviceClientModel device)
        {
            try
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Restart();
                double? before_weighing = null, after_weighing = null;
                while (stopwatch.ElapsedMilliseconds < _systemConfigStatic.SCM.WeighingTimeout)
                {
                    before_weighing = device.Communication.ReadSingle<double>(0, 0);
                    if (before_weighing != null)
                    {
                        LogAdd($"-[手工补液称] 获取到重量 ==> {before_weighing} g");
                        if (after_weighing != null)
                        {
                            double difference = Math.Round((double)(before_weighing - after_weighing), 1, MidpointRounding.AwayFromZero);
                            if (difference >= -0.3 && difference <= 0.3)
                            {
                                LogAdd($"-[手工补液称] 获取到的稳定值 ==> {before_weighing} g");
                                stopwatch.Stop();
                                return before_weighing;
                            }
                        }
                        after_weighing = before_weighing;
                    }
                    Thread.Sleep(500);
                }
                stopwatch.Stop();
            }
            catch (Exception ex)
            {

                LogAdd($"[手工补液称] 异常：{ex}");
            }

            return default;
        }


        /// <summary>
        /// 注液范围检查
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="Index">1:后称，2：补液称</param>
        /// <returns></returns>
        public ResultTypes InjRange_Check(ProductionData entity, int index)
        {
            string[] range = entity.RangeFluidRate.Split('-');
            double down_inj = Convert.ToDouble(range[0]);
            double standard = Convert.ToDouble(range[1]);
            double up_inj = Convert.ToDouble(range[2]);

            range = entity.RangeAfterWeighing.Split('-');
            double down_weiging = Convert.ToDouble(range[0]);
            double up_weiging = Convert.ToDouble(range[1]);

            TotalInjectionVolumeDeviationValue = entity.TotalInjectionVolumeDeviationValue = Math.Round(entity.ActualTotalInjectionVolume - standard, 2, MidpointRounding.AwayFromZero);

            var weighting = index == 1 ? entity.AfterWeighing : entity.RehydrationWeighing;
            ResultTypes types = (weighting, entity.ActualTotalInjectionVolume) switch
            {
                var k when k.weighting <= up_weiging && k.weighting >= down_weiging && k.ActualTotalInjectionVolume <= up_inj && k.ActualTotalInjectionVolume >= down_inj => ResultTypes.合格,
                var k when k.weighting > up_weiging => ResultTypes.称重偏重,
                var k when k.weighting < down_weiging => ResultTypes.称重偏轻,
                var k when k.ActualTotalInjectionVolume > up_inj => ResultTypes.注液量偏多,
                var k when k.ActualTotalInjectionVolume < down_inj => ResultTypes.注液量偏少,
                _ => ResultTypes.不合格,
            };

            if (!_parameterStatic.DecideParameter.EnableAfterInjection && (types == ResultTypes.称重偏轻 || types == ResultTypes.称重偏重))
            {
                LogAdd($"请注意!!![{entity.BarCode}] 未启用后称重检查==>>强制合格");
                return ResultTypes.合格;
            }
            if (!_parameterStatic.DecideParameter.EnableLiquidInjectionRange && (types == ResultTypes.注液量偏多 || types == ResultTypes.注液量偏少))
            {
                LogAdd($"请注意!!![{entity.BarCode}] 未启用注液量检查==>>强制合格");
                return ResultTypes.合格;
            }
            return types;
        }

        public DelegateCommand Closing => new DelegateCommand(() =>
        {
            KeyboardHook.UninstallationListening(24);
        });
        private void LogAdd(string str, MessageLevelType levelType = MessageLevelType.信息)
        {
            try
            {
                string errMsg = $"{DateTime.Now:HH:mm:ss} ==> {str}";
                UIWindows.Tools.Helper.DialogLogHelper.RunLog(errMsg, levelType);
                Application.Current.Dispatcher.Invoke(new Action(() => { Msg = errMsg; }));
            }
            catch (Exception ex)
            {
            }
        }
    }
}
